package io.legado.app.utils

import android.app.Activity.RESULT_OK
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContract

/**
 * 启动ActivityResultLauncher的泛型函数
 * 此函数用于在给定的ActivityResultLauncher上启动一个操作，而不传递任何输入值
 * 它封装了对launch函数的调用，传递null作为参数，简化了调用过程
 *
 * @param <T> 操作返回的数据类型，可以是任何类型
 */
fun <T> ActivityResultLauncher<T?>.launch() {
    launch(null)
}


class SelectImageContract : ActivityResultContract<Int?, SelectImageContract.Result>() {

    var requestCode: Int? = null

    /**
     * 创建一个意图，用于获取用户选择的图片
     *
     * @param context 上下文环境，用于创建意图
     * @param input 请求码的输入，可能为null
     * @return 返回一个意图，用于启动图片选择界面
     */
    override fun createIntent(context: Context, input: Int?): Intent {
        // 将输入的请求码保存到成员变量中，以便后续使用
        requestCode = input
        // 创建一个意图，其动作是获取内容，类型是图片，确保用户只能选择图片文件
        return Intent(Intent.ACTION_GET_CONTENT)
            .addCategory(Intent.CATEGORY_OPENABLE)
            .setType("image/*")
    }

    /**
     * 解析活动结果方法
     *
     * 此方法用于解析从其他活动返回的结果，根据结果代码和意图数据来构造一个结果对象
     *
     * @param resultCode 活动返回的结果代码，用于判断操作是否成功
     * @param intent 返回的意图对象，可能包含有返回数据
     * @return 返回一个Result对象，包含请求代码和可能的意图数据
     */
    override fun parseResult(resultCode: Int, intent: Intent?): Result {
        // 当结果代码为RESULT_OK时，表示操作成功
        if (resultCode == RESULT_OK) {
            // 创建并返回一个包含请求代码和意图数据的结果对象
            return Result(requestCode, intent?.data)
        }
        // 如果结果代码不是RESULT_OK，则创建并返回一个仅包含请求代码的结果对象
        return Result(requestCode, null)
    }

    data class Result(
        val requestCode: Int?,
        val uri: Uri? = null
    )

}

class StartActivityContract(private val cls: Class<*>) :
    ActivityResultContract<(Intent.() -> Unit)?, ActivityResult>() {

    /**
     * 创建一个Intent对象，并根据需要配置Intent
     *
     * @param context 上下文环境，用于创建Intent
     * @param input 可选的配置块，用于配置Intent的额外参数
     * @return 返回配置好的Intent对象
     */
    override fun createIntent(context: Context, input: (Intent.() -> Unit)?): Intent {
        // 创建Intent对象，指定目标活动为cls
        val intent = Intent(context, cls)

        // 如果有提供配置块，则应用配置块来设置Intent的额外参数
        input?.let {
            intent.apply(input)
        }

        // 返回配置好的Intent对象
        return intent
    }

    /**
     * 重写解析结果方法
     *
     * 该方法用于解析活动结果，根据结果码和可能的意图对象，封装成一个ActivityResult对象
     * 主要作用是将活动结果的相关信息进行封装，便于后续处理
     *
     * @param resultCode 结果码，表示活动结果的状态
     * @param intent 意图对象，可能包含活动结果的额外数据
     * @return 返回一个包含结果码和意图对象的ActivityResult实例
     */
    override fun parseResult(
        resultCode: Int, intent: Intent?
    ): ActivityResult {
        return ActivityResult(resultCode, intent)
    }

}
